package solutions.ferpa.ztest.intf;

import br.com.telescope.adsrt.dom.DomFlag;
import br.com.telescope.adsrt.dom.DomId;
import br.com.telescope.adsrt.dom.DomInteger;
import br.com.telescope.adsrt.dom.DomOpcao;
import br.com.telescope.adsrt.dom.DomSelectionBox;
import br.com.telescope.adsrt.dom.DomSelectionCheck;
import br.com.telescope.adsrt.dom.DomSourceCode;
import br.com.telescope.adsrt.dom.DomText;
import br.com.telescope.adsrt.dom.DomUpper;
import br.com.telescope.adsrt.lib.*;
import br.com.telescope.adsrt.lib.Field;
import br.com.telescope.t2.ModuleNavigator;
import br.com.telescope.t2.ServiceModel;
import br.com.telescope.t2.ServiceUrlManager;
import br.com.telescope.t2.exception.ApplicationRuntimeException;
import br.com.telescope.t2.exception.UnexpectedException;
import br.com.telescope.t2.feature.AbstractFeature;
import br.com.telescope.t2.feature.ListFeature;
import br.com.telescope.t2.feature.QueryFeature;
import br.com.telescope.t2.feature.SearchFeature;
import br.com.telescope.t2.feature.UpdateFeature;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import solutions.ferpa.ztest.ent.*;

/**
 * Configurações das interfaces do sistema.
 * <p>
 * Permite customizar algumas funcionalidades das interfaces do sistema:
 * <P>
 * * Alterar a ordenação padrão.
 * <P>
 * * Transformar campos opcionais em obrigatórios.
 * <P>
 * * Ocultar campos opcionais que não são utilizados pelo usuário.
 * <P>
 * * Definir a query da interface deve ser "relembrada".
 * <P>
 * * Redefinir o número de registro que aparecem na consulta (listagem).
 * <P>
 * * Customizar cores, tamanhos de fontes ou outras propriedades de CSS 
 * específicos da interface.
 * <P>
 * 
 * <P>
 * Observações: Campos obrigatórios na definição das entidades não são 
 * apresentados para "ocultação" ou "obrigatoriedade".
 * <P>
 * 
 * <P>
 * Exemplos de ordenação:
 * <P>
 * * Para ordenar os documentos da [t:#179604;title] apresentado no topo 
 * da lista os documentos que estão na situação "em manutenção", seguidos 
 * dos demais documentos ordenados por data de emissão e por número do 
 * documento:
 * <P>
 * P.ex.: Pode-se ordenar os documentos da tela de cadastro de documentos 
 * (notas fiscais) apresentando no topo da lista os documentos que estão 
 * com a situação "em manutenção", seguidos dos demais documentos 
 * ordenados por data de emissão (da mais atual para a mais antiga) e 
 * número do documento (do maior para o menor) utilizando a expressão:
 * <P>
 *  case when situacao_documento = 'M' then 0 else 1 end, data_emissao 
 * desc, numero desc
 * <P>
 * 
 * <P>
 * Telescope origin: RTPREF.CFG_INTERFACES_SISTEMAS
 * <P>
 * Base entity: RTSYSINF.INTERFACES_SISTEMAS
 * <P>
 * @author TELESCOPE - Build task T2 Web Interface Generator
 * <P>
 * @version 0.1
 */
public class CfgInterfacesSistemas extends ServiceModel {
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    public static final String GLOBAL_NAME = "RTPREF.CFG_INTERFACES_SISTEMAS";
    
    @Override
    public String globalName() {
        return GLOBAL_NAME;
    }
    
    {
        setTitle("Configurações das interfaces do sistema");
    }
    
    protected EntInterfacesSistemas base;
    protected EntInterfacesSistemas rec; // NEED_TJW1_COMPATIBILITY
    
    // Service parameters
    private DomUpper pInterface;
    
    // Record items
    private DomUpper aNome;
    private DomText aTitulo;
    private DomOpcao aTipoRegistro;
    private DomId aId;
    private DomSelectionBox aUnOrderBy;
    private DomText aUnExpressao;
    private DomInteger aUnLimit;
    private DomFlag aUnRememberQuery;
    private DomSelectionCheck aUnRequiredFields;
    private DomSelectionCheck aUnDisabledFields;
    private DomInteger aUnLovWidth;
    private DomInteger aUnLovHeight;
    private DomSourceCode aUnCss;
    
    // Query items
    private DomText qTitulo;
    private DomUpper qNome;
    
    @Override
    public String getBaseSql() {
        return "select BASE.*"
                + " from INTERFACES_SISTEMAS BASE";
    }
    
    @Override
    public String getBaseSqlWhereClause() {
        
        return " where base.tipo_registro = 'U'";
    }
    
    @Override
    public void initAttributes() {
        
        aNome = new DomUpper();
        aNome.context(ctx).name("NOME").label("Nome da Interface");
        
        aTitulo = new DomText();
        aTitulo.context(ctx).name("TITULO").label("Título");
        
        aTipoRegistro = new DomOpcao();
        aTipoRegistro.context(ctx).name("TIPO_REGISTRO").label("Tipo de registro").group(true);
        aTipoRegistro.addOption("I", "Implementação Custom");
        aTipoRegistro.addOption("PA_ATIVIDADES", "Política de acesso para atividades");
        aTipoRegistro.addOption("U", "User Interface");
        aTipoRegistro.setDefaultValue("U");
        
        aId = new DomId();
        aId.context(ctx).name("ID").label("Id");
        
        aUnOrderBy = new DomSelectionBox();
        aUnOrderBy.context(ctx).name("UN_ORDER_BY").label("Ordenar por").unbound(true);
        
        aUnExpressao = new DomText();
        aUnExpressao.context(ctx).name("UN_EXPRESSAO").label("Expressão").width(60).unbound(true);
        
        aUnLimit = new DomInteger();
        aUnLimit.context(ctx).name("UN_LIMIT").label("Limit").unbound(true);
        
        aUnRememberQuery = new DomFlag();
        aUnRememberQuery.context(ctx).name("UN_REMEMBER_QUERY").label("Relembrar query").unbound(true);
        
        aUnRequiredFields = new DomSelectionCheck();
        aUnRequiredFields.context(ctx).name("UN_REQUIRED_FIELDS").label("Campos obrigatórios").unbound(true);
        
        aUnDisabledFields = new DomSelectionCheck();
        aUnDisabledFields.context(ctx).name("UN_DISABLED_FIELDS").label("Campos desabilitados").unbound(true);
        
        aUnLovWidth = new DomInteger();
        aUnLovWidth.context(ctx).name("UN_LOV_WIDTH").label("LOV width").unbound(true);
        
        aUnLovHeight = new DomInteger();
        aUnLovHeight.context(ctx).name("UN_LOV_HEIGHT").label("LOV height").unbound(true);
        
        aUnCss = new DomSourceCode();
        aUnCss.context(ctx).name("UN_CSS").label("CSS").unbound(true);
        
        
        qTitulo = new DomText();
        qTitulo.context(ctx).name("TITULO").label("Título");
        
        qNome = new DomUpper();
        qNome.context(ctx).name("NOME").label("Nome da Interface");
    }
    
    @Override
    public void initParameters() {
        pInterface = new DomUpper(ctx, "INTERFACE", "Interface");
        pInterface.setValue(ctx.getParameter("P_INTERFACE"));
        pInterface.setUnbound(true);
    }
    
    @Override
    public List<Field> getParameters() {
        if (allParameters == null) {
            allParameters = new ArrayList<Field>();
            allParameters.add(pInterface);
        }
        return allParameters;
    }
    
    @Override
    public String getQueryPkColumn() {
        return "BASE.ID";
    }
    
    @Override
    public void setId(String value) {
        this.aId.setValue(value);
    }
    
    @Override
    public EntInterfacesSistemas getRecord() {
        if (base == null) {
            base = new EntInterfacesSistemas(ctx);
            rec = base;
        }
        return this.base;
    }
    
    @Override
    public String getContextName() {
        return aNome.toText();
    }
    
    @Override
    public String getDefaultOrderBy() {
        return "NOME, TITULO";
    }
    
    @Override
    public ModuleNavigator getDefaultModuleNavigator() {
        return new ModInterfacesSistemas();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="QUERY">
    public class FQuery extends QueryFeature {
        
        @Override
        public void initForm() {
            addField(qNome, "opt");
            addField(qTitulo, "opt");
        }
        
        {
            setFeatureName("QUERY");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="SEARCH">
    public class FSearch extends SearchFeature {
        
        @Override
        public void initForm() {
            addField(qNome, "search");
            addField(qTitulo, "search");
        }
        
        {
            setFeatureName("SEARCH");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="LIST">
    public class FList extends ListFeature {
        
        @Override
        public void initForm() {
            addField(aNome, "view");
            addField(aTitulo, "view");
        }
        
        {
            setFeatureName("LIST");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="UPDATE">
    public class FUpdate extends UpdateFeature {
        
        @Override
        public void initForm() {
            aNome.setEditable(false);
            addField(aNome, "view");
            aTitulo.setEditable(false);
            addField(aTitulo, "view");
            addField(aUnOrderBy, "opt");
            addField(aUnExpressao, "opt");
            addField(aUnLimit, "opt");
            addField(aUnRememberQuery, "opt");
            addField(aUnRequiredFields, "opt");
            addField(aUnDisabledFields, "opt");
            addField(aUnLovWidth, "opt");
            addField(aUnLovHeight, "opt");
            addField(aUnCss, "opt");
        }
        
        @Override
        public void preDisplay() {
            try {
                lerConfiguracoes();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void preUpdate() {
            try {
                salvarConfiguracoes();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void preFetch() {
            try {
                buscarIdInterface();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("UPDATE");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="initFeatures">
    
    @Override
    protected void initFeatures() {
        addFeature(new FQuery());
        addFeature(new FSearch());
        addFeature(new FList());
        addFeature(new FUpdate());
        super.initFeatures();
    }
    
    @Override
    public String getDefaultFeature() {
        return "QUERY";
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Getters and Setters">
    
    public String getNome() {
        return aNome.getValue();
    }
    
    public void setNome(String value) {
        this.aNome.setValue(value);
    }
    
    public String getTitulo() {
        return aTitulo.getValue();
    }
    
    public void setTitulo(String value) {
        this.aTitulo.setValue(value);
    }
    
    public String getTipoRegistro() {
        return aTipoRegistro.getValue();
    }
    
    public void setTipoRegistro(String value) {
        this.aTipoRegistro.setValue(value);
    }
    
    @Override
    public Long getId() {
        return aId.getValue();
    }
    
    public void setId(Long value) {
        this.aId.setValue(value);
    }
    
    public String getUnOrderBy() {
        return aUnOrderBy.getValue();
    }
    
    public void setUnOrderBy(String value) {
        this.aUnOrderBy.setValue(value);
    }
    
    public String getUnExpressao() {
        return aUnExpressao.getValue();
    }
    
    public void setUnExpressao(String value) {
        this.aUnExpressao.setValue(value);
    }
    
    public Integer getUnLimit() {
        return aUnLimit.getValue();
    }
    
    public void setUnLimit(Integer value) {
        this.aUnLimit.setValue(value);
    }
    
    public String getUnRememberQuery() {
        return aUnRememberQuery.getValue();
    }
    
    public void setUnRememberQuery(String value) {
        this.aUnRememberQuery.setValue(value);
    }
    
    public String getUnRequiredFields() {
        return aUnRequiredFields.getValue();
    }
    
    public void setUnRequiredFields(String value) {
        this.aUnRequiredFields.setValue(value);
    }
    
    public String getUnDisabledFields() {
        return aUnDisabledFields.getValue();
    }
    
    public void setUnDisabledFields(String value) {
        this.aUnDisabledFields.setValue(value);
    }
    
    public Integer getUnLovWidth() {
        return aUnLovWidth.getValue();
    }
    
    public void setUnLovWidth(Integer value) {
        this.aUnLovWidth.setValue(value);
    }
    
    public Integer getUnLovHeight() {
        return aUnLovHeight.getValue();
    }
    
    public void setUnLovHeight(Integer value) {
        this.aUnLovHeight.setValue(value);
    }
    
    public String getUnCss() {
        return aUnCss.getValue();
    }
    
    public void setUnCss(String value) {
        this.aUnCss.setValue(value);
    }
    public String getQueryNome() {
        return qNome.getQueryValue();
    }
    
    public void setQueryNome(String value) {
        this.qNome.setQueryValue(value);
    }
    public String getQueryTitulo() {
        return qTitulo.getQueryValue();
    }
    
    public void setQueryTitulo(String value) {
        this.qTitulo.setQueryValue(value);
    }
    
    public String getParameterInterface() {
        return pInterface.getValue();
    }
    
    public void setParameterInterface(String value) {
        pInterface.setValue(value);
    }
    // </editor-fold>
    
    /**
     * Buscar ID da interface.
     * <p>
     * Quando o nome global da interface for informado por parâmetro, busca o 
     * ID da mesma para permitir a edição.
     * <P>
     */
    private void buscarIdInterface() throws AdsException {
        // <user-code id="11421889" parentId="11421831" hashcode="-77846567" length="177">
        ctx.readFields(aId, aNome);
        if (aId.isNull() && aNome.isNotNull()) {
            getRecord().findByNome(aNome.getValue());
            ctx.setParameter("A_ID", getRecord().valueOfNome());
        }
        // </user-code>
    }
    
    /**
     * Ler configurações.
     * <p>
     * Executa a leitura das configurações da interface.
     */
    private void lerConfiguracoes() throws AdsException {
        // <user-code id="2939422" parentId="2939421" hashcode="723c0125" length="2070">
        // import br.com.telescope.t2.ServiceUrlManager;
        // import br.com.telescope.t2.ServiceModel;
        // import br.com.telescope.t2.exception.UnexpectedException;
        // import java.util.HashSet;
        // import br.com.telescope.t2.feature.AbstractFeature;
        String nome = getRecord().valueOfNome();
        String key = nome + ".";
        ServiceUrlManager mgr = ServiceUrlManager.getInstance();
        ServiceModel block;
        try {
            block = mgr.getClassForService(nome).newInstance();
        } catch (Exception ex) {
            throw new UnexpectedException(ex);
        }
        block.instantiate(ctx);
        
        HashSet<String> required = new HashSet<String>();
        for (AbstractFeature feature : block.getFeatures()) {
            for (FieldUsage fu : feature.getForm().getFieldUsages()) {
                if (fu.getUsage().equals("rqd")) {
                    required.add(fu.getField().getName());
                }
            }
        }
        for (Field item : block.allAttributes()) {
            aUnOrderBy.addOption(item.getSqlExpression(), item.getSqlExpression());
            if (!required.contains(item.getName())) {
                String label = item.getLabel();
                if (label != null) label = " (" + label + ")"; else label = "";
                aUnDisabledFields.addOption(item.getName(), item.getName() + label);
                aUnRequiredFields.addOption(item.getName(), item.getName() + label);
            }
        }
        
        String ob = ctx.getPreference(key + "ORDER_BY");
        String obDefault = block.getDefaultOrderBy();
        if (ob == null || ob.isEmpty()) {
            aUnOrderBy.setValue(obDefault);
            aUnExpressao.setValue(obDefault);
        } else {
            aUnOrderBy.setValue(ob);
            aUnExpressao.setValue(ob);
        }
        aUnDisabledFields.setValue(ctx.getPreference(key + "DISABLED_FIELDS"));
        aUnRequiredFields.setValue(ctx.getPreference(key + "REQUIRED_FIELDS"));
        aUnLovHeight.setValue(ctx.getPreference(key + "LOV_HEIGHT"));
        aUnLovWidth.setValue(ctx.getPreference(key + "LOV_WIDTH"));
        aUnCss.setValue(ctx.getPreference(key + "CSS"));
        aUnLimit.setValue(ctx.getPreference(key + "LIMIT"));
        aUnRememberQuery.setValue(ctx.getPreference(key + "REMEMBER_QUERY",
                ctx.getPreference("RT.UI.REMEMBER_QUERY", "S")));
        // </user-code>
    }
    
    /**
     * Salvar configurações.
     * <p>
     * Salva todas as configurações para a interface.
     * <P>
     */
    private void salvarConfiguracoes() throws AdsException {
        // <user-code id="2939424" parentId="2939423" hashcode="-374bfc4" length="1214">
        String key = getRecord().valueOfNome() + ".";
        String nome = getRecord().valueOfNome();
        
        ServiceUrlManager mgr = ServiceUrlManager.getInstance();
        ServiceModel block;
        try {
            block = mgr.getClassForService(nome).newInstance();
        } catch (Exception ex) {
            throw new UnexpectedException(ex);
        }
        block.instantiate(ctx);
        
        String obDefault = block.getDefaultOrderBy();
        if (!obDefault.equals(aUnExpressao.getValue())) {
            ctx.setPreference(key + "ORDER_BY", aUnExpressao.getValue());
        }
        ctx.setPreference(key + "DISABLED_FIELDS", aUnDisabledFields.getValue());
        ctx.setPreference(key + "REQUIRED_FIELDS", aUnRequiredFields.getValue());
        ctx.setPreference(key + "CSS", aUnCss.getValue());
        ctx.setPreference(key + "LIMIT", aUnLimit.toStringValue());
        ctx.setPreference(key + "LOV_HEIGHT", aUnLovHeight.isNull() ? null : aUnLovHeight.toStringValue());
        ctx.setPreference(key + "LOV_WIDTH", aUnLovWidth.isNull() ? null : aUnLovWidth.toStringValue());
        
        String def = ctx.getPreference("RT.UI.REMEMBER_QUERY", "S");
        if (def.equals(aUnRememberQuery.getValue())) {
            ctx.setPreference(key + "REMEMBER_QUERY", null);
        } else {
            ctx.setPreference(key + "REMEMBER_QUERY", aUnRememberQuery.getValue());
        }
        // </user-code>
    }
    
    @Override
    public String getJsServiceFile() {
        return "ui/rtpref/cfg_interfaces_sistemas.js";
    }
}
